package com.xuecheng.order.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.UUID;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xuecheng.commons.constants.OrdersConstants;
import com.xuecheng.commons.enums.ErrorCode;
import com.xuecheng.commons.model.dto.RecordDto;
import com.xuecheng.commons.model.vo.CoursePubIndexVo;
import com.xuecheng.commons.model.vo.OrdersVo;
import com.xuecheng.commons.model.vo.ResponseResult;
import com.xuecheng.commons.utils.AuthInfoHolder;
import com.xuecheng.commons.utils.BeanHelper;
import com.xuecheng.learning.api.LearningClient;
import com.xuecheng.order.domain.Orders;
import com.xuecheng.order.domain.Payment;
import com.xuecheng.order.mappers.OrdersMapper;
import com.xuecheng.order.service.OrdersService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.order.service.PaymentService;
import com.xuecheng.order.utils.PayUtils;
import com.xuecheng.search.api.SearchClient;
import com.xuecheng.web.exception.BusinessException;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * <p>
 * 订单 服务实现类
 * </p>
 *
 * @author itheima
 * @since 2022-07-26
 */
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements OrdersService {

    //注入课程搜索的feign接口
    @Autowired
    SearchClient searchClient;

    @Autowired
    PayUtils payUtils;

    @Autowired
    PaymentService paymentService;

    @Autowired
    LearningClient learningClient;

    //创建订单数据，存入数据库，返回订单编号
    @Override
    public ResponseResult<String> createOrder(Long coursePubId) {
        //1.获取当前用户id
        Long userId = AuthInfoHolder.getUserId();
        //2.查询当前用户是否已经购买过此课程
        LambdaQueryWrapper<Orders> qw1 = new LambdaQueryWrapper();
        qw1.eq(Orders::getUserId,userId);
        qw1.eq(Orders::getCoursePubId,coursePubId);
        qw1.eq(Orders::getStatus, OrdersConstants.ORDER_PAID_STATUS);
        Orders one = this.getOne(qw1);
        if (one != null) {
             throw new BusinessException(ErrorCode.ORDERERROR);
        }
        //3.查询当前课程是否已经具备初始态的订单，如果存在，返回订单号
        LambdaQueryWrapper<Orders> qw2 = new LambdaQueryWrapper();
        qw2.eq(Orders::getUserId,userId);
        qw2.eq(Orders::getCoursePubId,coursePubId);
        qw2.eq(Orders::getStatus, OrdersConstants.ORDER_INIT_STATUS);
        Orders two = this.getOne(qw2);
        if (two != null) {
            return ResponseResult.okResult(two.getOrderNo());
        }
        //4.构造订单数据
        ResponseResult<CoursePubIndexVo> result = searchClient.findById(coursePubId);
        CoursePubIndexVo coursePub = result.getData();
        if (coursePub == null) {
            throw new BusinessException(ErrorCode.PAYERROR);
        }
        Orders orders = new Orders();
        orders.setOrderNo(UUID.randomUUID().toString(true));  //唯一的字符串
        orders.setCoursePubId(coursePubId);
        orders.setCoursePubName(coursePub.getName());
        orders.setCompanyId(coursePub.getCompanyId());
        orders.setUserId(userId);
        orders.setCreateDate(new Date());
        orders.setPrice(1l);        //单位是分，1分钱
        orders.setStatus(OrdersConstants.ORDER_INIT_STATUS);
        //5.存入到数据库中
        boolean save = this.save(orders);
        if (!save) {
            throw new BusinessException(ErrorCode.PAYERROR);
        }
        //6.构造返回值
        return ResponseResult.okResult(orders.getOrderNo());
    }

    //查询订单支付状态
    @GlobalTransactional
    @Override
    public ResponseResult<OrdersVo> queryOrder(String orderNo) {
        //1.判断订单是否存在
        LambdaQueryWrapper<Orders> qw = new LambdaQueryWrapper<>();
        qw.eq(Orders::getOrderNo,orderNo);
        Orders orders = this.getOne(qw);
        if (orders == null) {
            throw new BusinessException(ErrorCode.NOTFOUND);
        }
        //2.如果订单的状态是未支付，查询微信的支付结果
        if (orders.getStatus().equals(OrdersConstants.ORDER_INIT_STATUS)) {
            Boolean payment = payUtils.checkPayment(orderNo);
            if (payment) {
                //3.如果微信结果存在，完成后续业务
                //3.1 修改订单表数据(orders)
                orders.setStatus(OrdersConstants.ORDER_PAID_STATUS);
                this.updateById(orders);
                //3.2 修改支付信息表数据(payment)
                LambdaQueryWrapper<Payment> pqw = new LambdaQueryWrapper<>();
                pqw.eq(Payment::getOrderNo,orderNo);
                Payment payment1 = new Payment();
                payment1.setStatus(OrdersConstants.PAID.toString());
                paymentService.update(payment1,pqw);  //更新的对象，更新的条件
                //3.3 调用feign接口保持/更新选课记录
                RecordDto recordDto = new RecordDto();
                recordDto.setCoursePubId(orders.getCoursePubId());
                recordDto.setUserId(orders.getUserId());
                learningClient.saveRecord(recordDto);
            }
        }
        //4.返回
        OrdersVo vo = BeanHelper.copyProperties(orders, OrdersVo.class);
        return ResponseResult.okResult(vo);
    }

    /**
     * 处理超时订单
     */

    @Override
    public void getPayment() {
        //1.查询超时，未支付的订单
        LambdaQueryWrapper<Orders> qw = new LambdaQueryWrapper<>();
        qw.eq(Orders::getStatus,OrdersConstants.ORDER_INIT_STATUS);
        String string = DateUtil.offsetMinute(new Date(), -15).toString();  //推算15分钟之前的时间
        qw.lt(Orders::getCreateDate,string);
        List<Orders> list = this.list(qw);
        //2.循环所有超时订单
        if (list != null) {
            for (Orders orders : list) {
                //获取每个订单，调用微信查询支付状态
                Boolean payment = payUtils.checkPayment(orders.getOrderNo());
                if (payment) {
                    //3.1 已支付，完成后续业务
                    //3.1 修改订单表数据(orders)
                    orders.setStatus(OrdersConstants.ORDER_PAID_STATUS);
                    this.updateById(orders);
                    //3.2 修改支付信息表数据(payment)
                    LambdaQueryWrapper<Payment> pqw = new LambdaQueryWrapper<>();
                    pqw.eq(Payment::getOrderNo,orders.getOrderNo());
                    Payment payment1 = new Payment();
                    payment1.setStatus(OrdersConstants.PAID.toString());
                    paymentService.update(payment1,pqw);  //更新的对象，更新的条件
                    //3.3 调用feign接口保持/更新选课记录
                    RecordDto recordDto = new RecordDto();
                    recordDto.setCoursePubId(orders.getCoursePubId());
                    recordDto.setUserId(orders.getUserId());
                    learningClient.saveRecord(recordDto);
                } else {
                    //3.2 未支付,调用微信关闭订单，修改订单表改为关闭
                    Boolean closeOrder = payUtils.closeOrder(orders.getOrderNo());
                    if (closeOrder) {
                        orders.setStatus(OrdersConstants.ORDER_CLOSED_STATUS);
                        this.updateById(orders);
                    }
                }
            }
        }
    }
}
